Annotate DependencyInjection to make it linker friendly - #40227
Conversation
|
Tagging subscribers to this area: @eerhardt, @maryamariyan |
|
cc @dadhi @alexmg @seesharper @tillig @ENikS @ipjohnson @pakrym More on this general feature here https://github.com/mono/linker/blob/master/docs/design/reflection-flow.md |
|
Is this for DI libraries or client code? Will it remove client constructors marked for injection? |
|
DI libraries. Today if you link the entire application it will remove constructors use in DI registrations because the linker can't see the which constructors are in use: var services = new ServiceCollection();
services.AddSingleton<IFoo, Foo>();
var sp = services.BuildServiceProvider();
var foo = sp.GetService<IFoo>();
foo.Bar();This would fail before this PR because Foo's constructor would be removed after linking. The annotations instruct the linker to preserve constructors of the generic second argument (the implementation type in this case). |
|
But what about constructors marked with [InjectionConstructor] attributes? I am assuming these will be gone as well? |
|
@ENikS I don't know if there's a pattern to preserve those. Usually attribute only approaches require assembly scanning, which is also not linker friendly. It's possible that pattern is just incompatible and will result in the user needing to manually preserve those types. |
|
Without that MEF, MEF2, Unity and probable some other are not compatible with the pattern. @davidfowl thank you for heads up! |
Correct. We haven't gotten to making MEF and MEF2 linker friendly. It isn't scheduled for .NET 5, but it may be included in .NET 6. |
|
@davidfowl Thanks for letting us know about this. So to preserve the constructors for a given type, the type needs to be mentioned in a method taking a |
It's the only way that works with the dataflow analysis within the linker. The problem is basically that code like: var o = Activator.CreateInstance(someType);may or may not work after trimming, depending on whether the default constructor for You can get rid of that warning four ways:
|
|
Does RequiresUnreferencedCodeAttribute disable trimming on the assembly/type/member specified? |
No. It is a way to mark an API as unsafe for trimming. This lets the caller know that they should either call a different API or they need to do extra work to make this call safe (e.g. explicitly preserve types/methods/properties/etc). For example |
Does it have to be new attribute? Can you use existing MEF attributes? Perhaps you could add an interface, so something like Unity could add to injection attributes as well? Without support for custom constructor annotations you are cutting out huge chunk of corporate users that use third party IOC containers. Perhaps this could be revisited? |
|
Nothing is being cut, those applications will still work with less aggressive trimming modes, they just won't be able to trim the assemblies completely (or at all). BTW, this trimming mode isn't the default and we're still a while away from being able to trim our own framework fully. We're just getting started here. |
|
I understand, just trying to make sure this scenario is considered from the beginning and is not an afterthought when it is too late to change |
|
@davidfowl thanks for the heads up. Can we apply |
You can apply it to just the API surface but the linker warns if it isn't applied transitively. |
|
Thanks @MichalStrehovsky for such a detailed explanation.👍 Is there any way we can start to test this? Is it possible to enable this using the preview 7 bits? I've tried Finally I was just wondering if this is something that is mainly meant for Xamarin apps or do guys you see this as general feature that eventually can be applied to all .Net 5 apps? |
|
@seesharper I made this for you https://github.com/davidfowl/LinkedAspNetCoreApplication. Run it with |
|
Wow, that was fast. Thanks a lot, David. I'll have a look first thing tomorrow. Again, I gotta hand it to you guys. The way that you involve the community early on new features is just priceless. 👍💪 Really appreciate it |
* Annotate DependencyInjection to make it linker friendly Fix dotnet#39745
Fix #39745
With this change, the remaining (current) ILLinker warnings for the 2 DependencyInjection libraries are: